package com.doxiaopu.students.order.service.impl;

import com.doxiaopu.students.component.exception.InsufficientBalanceException;
import com.doxiaopu.students.order.entity.Order;
import com.doxiaopu.students.order.mapper.OderMapper;
import com.doxiaopu.students.order.mapper.OrderVOMapper;
import com.doxiaopu.students.order.service.IOrderService;
import com.doxiaopu.students.order.vo.OrderVO;
import com.doxiaopu.students.organization.entity.OrderRevenueSettings;
import com.doxiaopu.students.organization.entity.Organization;
import com.doxiaopu.students.organization.mapper.OrderRevenueSettingsMapper;
import com.doxiaopu.students.organization.mapper.OrganizationMapper;
import com.doxiaopu.students.product.entity.GroupSingleRebate;
import com.doxiaopu.students.product.entity.Single;
import com.doxiaopu.students.product.mapper.GroupSingleRebateMapper;
import com.doxiaopu.students.product.mapper.SingleMapper;
import com.doxiaopu.students.product.vo.SingleVO;
import com.doxiaopu.students.user.entity.MerchantData;
import com.doxiaopu.students.user.entity.PlatformData;
import com.doxiaopu.students.user.entity.User;
import com.doxiaopu.students.user.mapper.MerchantDataMapper;
import com.doxiaopu.students.user.mapper.PlatformDataMapper;
import com.doxiaopu.students.user.mapper.UserMapper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

@Service
@Primary
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private OderMapper oderMapper;
    @Autowired
    private OrderVOMapper orderVOMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderRevenueSettingsMapper orderRevenueSettingsMapper;
    @Autowired
    private GroupSingleRebateMapper groupSingleRebateMapper;
    @Autowired
    private MerchantDataMapper merchantDataMapper;
    @Autowired
    private PlatformDataMapper platformDataMapper;
    @Autowired
    private SingleMapper singleMapper;
    @Autowired
    private OrganizationMapper organizationMapper;

    @Override
    @Transactional
    public Long createOrder(Order order,Integer id) throws InsufficientBalanceException {
        Date now = new Date();
        // 1、根据订单扣除消费者余额
        User user = userMapper.getById(id);
        Integer balance = user.getBalance()-order.getAllPrice();
        if (balance>=0){
            user.setBalance(balance);
            user.setModifiedUser(user.getUsername());
            user.setModifiedTime(now);
            updateBalance(user);
        }else {
            throw new InsufficientBalanceException("用户的余额不足，不能完成支付");
        }

        // 2、查出社团与社联的分配比例
        OrderRevenueSettings orderRevenueSettings = selectInfo();
        // 3、查出订单的总返利额
        GroupSingleRebate groupSingleRebate = findRebate(order.getSingleid());
        // 4、给社团的累计返利订单和累计返利额添加
        Integer addAssociation = order.getSallnumber()*groupSingleRebate.getRebateAmount() * orderRevenueSettings.getMassOrganizationGains()/100;
        Organization organization = findOrganizationBymassOrganizationId(order.getMassOrganizationId());
        organization.setBalance(organization.getBalance()+addAssociation);
        organization.setCumulativeOrder(organization.getCumulativeOrder()+order.getSallnumber());
        organization.setModifiedUser(user.getUsername());
        organization.setModifiedTime(now);
        updateOrganization(organization);
        // 5、给社联的累计返利订单和累计返利额添加
        Integer addUnite = order.getSallnumber()*groupSingleRebate.getRebateAmount() * orderRevenueSettings.getStudentsUnionGains()/100;
        Organization UniteOrganization1 = findOrganizationBymassOrganizationId(organization.getSuperiorsId());
        UniteOrganization1.setBalance(UniteOrganization1.getBalance()+addUnite);
        UniteOrganization1.setCumulativeOrder(UniteOrganization1.getCumulativeOrder()+order.getSallnumber());
        UniteOrganization1.setModifiedUser(user.getUsername());
        UniteOrganization1.setModifiedTime(now);
        updateOrganization(UniteOrganization1);
        // 6、根据平台抽成比例增加平台余额
        Integer allPrice = order.getAllPrice()-addAssociation-addUnite;
        PlatformData platformData = findPlatformData();
        Integer platformBalance = allPrice*platformData.getTakeAPercentage()/100+platformData.getBalance();
        platformData.setBalance(platformBalance);
        updatePlatformData(platformData);
        // 7、增加商家余额
        MerchantData merchantData = selectMerchantDataByFlagid(order.getSingleid());
        merchantData.setBalance(allPrice-platformBalance+merchantData.getBalance());
        updateMerchantData(merchantData);
        // 8、在团单中增加销量记录
        Single single = new Single();
        SingleVO singleVO = findSingleById(order.getSingleid());
        single.setFlagid(order.getSingleid());
        single.setSalesVolume(singleVO.getSalesVolume()+order.getSallnumber());
        updateSingleById(single);

        order.setUserid(user.getTUserId());
        //订单编号
        String ordernumber =getCode(id);
        //二维码图片地址
        String qrurl = getURCodePicture(ordernumber);
        // 核销码
        String  checkOffCode=genVerifyCode();
        Long orderId = uniqId();
        //向数据库存入二维码地址、订单编号、核销码、订单id
        order.setQrurl(qrurl);
        order.setOrdernumber(ordernumber);
        order.setOrderId(orderId);
        order.setOrdertime(createTime());
        order.setCheckOffCode(checkOffCode);
        //创建订单
        Integer raws = addOder(order);
        return orderId;
    }

    @Override
    public List<Order> getOrderList(Integer id) {
        User user = userMapper.getById(id);
        return getOder(user.getTUserId());
    }

    @Override
    public List<Order> getOrderListByType(Integer types,Integer id) {
        User user = userMapper.getById(id);
        return getOderByType(types,user.getTUserId());
    }

    @Override
    public Map<String, Object> getAdminOrderList(OrderVO orderVO, Integer id) {
        Integer currentPage = (orderVO.getCurrentPage() - 1) * orderVO.getPageSize();
        orderVO.setCurrentPage(currentPage);
        User user = userMapper.getById(id);
        Integer types = user.getTypes();
        System.err.print(types);
        if(types.equals(4)) {
            orderVO.setUserid(null);
        }else {
            orderVO.setUserid(user.getTUserId());
        }
        System.err.print("orderVO:"+orderVO);
        List<OrderVO> data = getAdminOderList(orderVO);
        Integer total = selectTatal(orderVO);
        Map<String, Object> res = new HashMap<>();
        res.put("data",data);
        res.put("total",total);
        return res;
    }

    @Override
    public Order findOrderById(Long orderId) {
        Order order = findOrderByOrderId(orderId);
        return order;
    }

    /**
     * 增加订单
     * @param order
     * @return
     */
    private Integer addOder(Order order){
        return oderMapper.addOder(order);
    }

    /**
     * 生成订单二维码和地址地址
     * @param odrernuber
     * @return
     */
    private  String getURCodePicture(String odrernuber){
        int width = 600;  //定义图片宽度
        int height = 600;   //定义图片高度
        String type = "png";//定义图片格式
        String content = odrernuber;//定义扫描二维码内容
        //定义二维码的配置，在这里用的是HashmAP
        HashMap hints = new HashMap();
        //定义字符集，utf-8
        hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
        //设置容错等级
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        //设置边距，二维码边距空白宽度为0
        hints.put(EncodeHintType.MARGIN,2);
        Random rand = new Random();
        int randNum = rand.nextInt(999999999)+1000000000;
        String QRName = Integer.toString(randNum);
        try {
            //生成二维码对象，传入各种属性
            BitMatrix bitMatrix = new MultiFormatWriter()
                    .encode(content, BarcodeFormat.QR_CODE,width,height,hints);
            //定义路径
            Path file = new File("./src/main/resources/static/images/"+QRName+".png").toPath();
            //生成路径并生成文件
            MatrixToImageWriter.writeToPath(bitMatrix,type,file);
        }catch(Exception e){
            e.printStackTrace();
        }
        return "/"+QRName+".png";
    }

    /**
     * 获得订单编号
     * @param id
     * @param
     * @return
     */
    private String getCode(Integer id) {
        Random rand = new Random();
        int randNum = rand.nextInt(99);
        return System.currentTimeMillis()+""+id+""+randNum;
    }
    private String createTime() {
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String line = sdf.format(now);
        return line;
    }
    /**
     * 查询所有订单
     * @return
     */
    private List<Order> getOder(String userid) {
        return oderMapper.getOder(userid);
    };

    /**
     * 通过type查订单
     * @param types
     * @return
     */
    private List<Order> getOderByType(Integer types,String userid) {
        return oderMapper.getOderByType(types,userid);
    };
    /**
     * 生成订单商品核销码
     *
     * @return
     */
    public static String genVerifyCode() {
        String year = new SimpleDateFormat("yy").format(new Date());
        String day = String.format("%tj", new Date());
        double random = Math.random() * 10000000;
        while (random < 1000000) {
            random = Math.random() * 10000000;
        }
        int intRandom = Double.valueOf(random).intValue();
        String verifyCode = year + day + intRandom;
        return verifyCode;
    }
    /**
     * 获得后台订单列表
     * @param orderVO
     * @return
     */
    private List<OrderVO> getAdminOderList(OrderVO orderVO){
        return orderVOMapper.getAdminOderList(orderVO);
    };
    /**
     * 获得后台订单列表的总条数
     * @param orderVO
     * @return
     */
    private Integer selectTatal(OrderVO orderVO){
        return orderVOMapper.selectTatal(orderVO);
    };
    /**
     * 更改用户余额
     * @param user
     * @return
     */
    private Integer updateBalance(User user){
        return userMapper.updateBalance(user);
    };
    /**
     * 查询信息
     * @param
     * @return
     */
    private OrderRevenueSettings selectInfo(){
        return orderRevenueSettingsMapper.selectInfo();
    };

    /**
     * 通过rebateid查询返利信息
     * @param rebateid
     * @return
     */
    private GroupSingleRebate findRebate(String rebateid) {
        return groupSingleRebateMapper.findRebate(rebateid);
    };
    /**
     * 查询平台的收益信息
     * @return
     */
    private PlatformData findPlatformData(){
        return platformDataMapper.findPlatformData();
    };
    /**
     * 编辑平台的收益信息
     * @param platformData
     * @return
     */
    private Integer updatePlatformData(PlatformData platformData){
        return platformDataMapper.updatePlatformData(platformData);
    };
    /**
     * 更改商户的数据信息
     * @param
     * @return
     */
    private Integer updateMerchantData(MerchantData merchantData){
        return merchantDataMapper.updateMerchantData(merchantData);
    };
    /**
     * 通过flagid查询商家的数据信息
     * @param flagid
     * @return
     */
    private MerchantData selectMerchantDataByFlagid(String flagid){
        return merchantDataMapper.selectMerchantDataByFlagid(flagid);
    };
    /**
     * 更改团单信息
     * @param single
     * @return
     */
    private Integer updateSingleById(Single single){
        return singleMapper.updateSingleById(single);
    };
    /**
     * 通过团单flagid查询团单的详情信息
     * @param flagid
     * @return
     */
    private SingleVO findSingleById(String flagid){
        return singleMapper.findSingleById(flagid);
    };
    /**
     * 通过massOrganizationId查询累计返利订单和余额
     * @param massOrganizationId
     * @return
     */
    private Organization findOrganizationBymassOrganizationId(String massOrganizationId){
        return organizationMapper.findOrganizationBymassOrganizationId(massOrganizationId);
    };

    /**
     * 编辑余额和累计订单
     * @param organization
     * @return
     */
    private Integer updateOrganization(Organization organization){
        return organizationMapper.updateOrganization(organization);
    };
    /**
     * 查询订单二维码
     * @param orderId
     * @return
     */
    private Order findOrderByOrderId(Long orderId){
        return oderMapper.findOrderByOrderId(orderId);
    };
    private static long uniqId() {
//        Random random = new Random();
//        String nanoRandom = System.nanoTime() + "" + random.nextInt(99999);
//        int hash = Math.abs(UUID.randomUUID().hashCode());
//        int needAdd = 19 - String.valueOf(hash).length() + 1;
//        return Long.valueOf(hash + "" + nanoRandom.substring(needAdd));
        return ThreadLocalRandom.current().nextInt(1, 999999999 + 1);
    }
}
